package com.itheima.app.manager;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.itheima.app.interceptor.UserHolder;
import com.itheima.app.log.LogWith;
import com.itheima.app.mq.MovementScoreMQSend;
import com.itheima.autoconfig.oss.OssTemplate;
import com.itheima.domain.db.Log;
import com.itheima.domain.db.UserInfo;
import com.itheima.domain.mongo.Comment;
import com.itheima.domain.mongo.Movement;
import com.itheima.domain.mongo.Visitor;
import com.itheima.service.db.UserInfoService;
import com.itheima.service.mongo.CommentService;
import com.itheima.service.mongo.MovementService;
import com.itheima.service.mongo.VisitorService;
import com.itheima.util.ConstantUtil;
import com.itheima.vo.CommentVo;
import com.itheima.vo.MovementVo;
import com.itheima.vo.PageBeanVo;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Component
@SuppressWarnings("all")
public class MovementManager {
    @DubboReference
    private MovementService movementService;
    @Autowired
    private OssTemplate ossTemplate;
    @DubboReference
    private UserInfoService userInfoService;
    @DubboReference
    private CommentService commentService;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @DubboReference
    private VisitorService visitorService;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;
    @Autowired
    private MovementScoreMQSend movementScoreMQSend;

    //发布动态
    @LogWith(type = "0201")
    public void saveMovement(Movement movement, MultipartFile[] imageContent) throws IOException {
        //根据token获取userId
        Long userId = UserHolder.get().getId();
        //声明图片地址集合
        List medias = new ArrayList<>();
        //判断图片非空
        if (ArrayUtil.isNotEmpty(imageContent)) {
            //不为空时通过遍历使用OSS上传图片
            for (MultipartFile multipartFile : imageContent) {
                String url = ossTemplate.upload(multipartFile.getOriginalFilename(), multipartFile.getInputStream());
                //存入集合
                medias.add(url);
            }
        }
        //给动态实体类空值赋值
        //动态主键id
        movement.setId(ObjectId.get());
        //动态userId
        movement.setUserId(userId);
        //动态图片地址
        movement.setMedias(medias);
        //动态动态审核状态
        movement.setState(0);
        //动态创建时间
        movement.setCreated(System.currentTimeMillis());
        //动态可见设置
        movement.setSeeType(1);
        movementService.saveMovement(movement);
        //把动态id发布给MQ
        rocketMQTemplate.convertAndSend("tanhua-movement-check",movement.getId().toHexString());
        //记录MovementScore发布给MQ
        movementScoreMQSend.sendMovement(userId,movement.getId(),MovementScoreMQSend.MOVEMENT_PUBLISH);
    }

    //查询我的动态
    public ResponseEntity findMyMovement(Long userId, Integer pageNum, Integer pageSize) {
        //调用业务层获取“我的动态”分页类
        PageBeanVo pageBeanVo = movementService.findMyMovement(userId, pageNum, pageSize);
        //因为返回值需要用户的详细信息 所以创建一个新的实体类集合
        List<MovementVo> movementVos = new ArrayList<>();
        //获取我的动态集合
        List<Movement> movementList = (List<Movement>) pageBeanVo.getItems();
        //非空判断
        if (CollectionUtil.isNotEmpty(movementList)) {
            //遍历我的动态集合
            for (Movement movement : movementList) {
                //根据动态中的userid获取user的详细信息
                UserInfo userInfo = userInfoService.findById(movement.getUserId());
                //创建满足返回值的实体类 并赋值
                MovementVo movementVo = new MovementVo();
                movementVo.setUserInfo(userInfo);
                movementVo.setUserId(movement.getUserId());
                movementVo.setMovement(movement);
                if (stringRedisTemplate.hasKey(StrUtil.format(ConstantUtil.MOVEMENT_LIKE, movement.getId(), userId))) {
                    movementVo.setHasLiked(1);
                }
                //存入集合
                movementVos.add(movementVo);
            }
        }
        //把分页类中的集合改为满足返回值条件的集合
        pageBeanVo.setItems(movementVos);
        //返回页面
        return ResponseEntity.ok(pageBeanVo);
    }

    //查询好友动态
    public ResponseEntity findFriendMovement(Integer pageNum, Integer pageSize) {
        //根据token获取userId
        Long userId = UserHolder.get().getId();
        //调用业务层获取“好友动态”分页类
        PageBeanVo pageBeanVo = movementService.findFriendMovement(userId, pageNum, pageSize);
        //因为返回值需要用户的详细信息 所以创建一个新的实体类集合
        List<MovementVo> movementVos = new ArrayList<>();
        //获取好友动态集合
        List<Movement> items = (List<Movement>) pageBeanVo.getItems();
        //判断非空
        if (CollectionUtil.isNotEmpty(items)) {
            //遍历集合
            for (Movement item : items) {
                //根据好友动态信息中的userId获取用户详细信息
                UserInfo userInfo = userInfoService.findById(item.getUserId());
                //创建满足返回值的实体类 并赋值
                MovementVo movementVo = new MovementVo();
                movementVo.setUserInfo(userInfo);
                movementVo.setUserId(item.getUserId());
                movementVo.setMovement(item);
                if (stringRedisTemplate.hasKey(StrUtil.format(ConstantUtil.MOVEMENT_LIKE, item.getId(), userId))) {
                    movementVo.setHasLiked(1);
                }
                //存入集合
                movementVos.add(movementVo);
            }
        }
        //把分页类中的集合改为满足返回值条件的集合
        pageBeanVo.setItems(movementVos);
        //返回页面
        return ResponseEntity.ok(pageBeanVo);
    }

    //查看推荐动态
    public ResponseEntity findRecommendMovement(Integer pageNum, Integer pageSize) {
        //根据token获取userId
        Long userId = UserHolder.get().getId();
        //调用业务层获取推荐动态分页类
        PageBeanVo pageBeanVo = movementService.findRecommendMovement(userId, pageNum, pageSize);
        //创建满足返回值的vo类集合
        List<MovementVo> movementVos = new ArrayList<>();
        //取出分页类中的推荐动态集合
        List<Movement> items = (List<Movement>) pageBeanVo.getItems();
        //判断非空
        if (CollectionUtil.isNotEmpty(items)) {
            //遍历
            for (Movement item : items) {
                //根据动态类中的userId获取user详细信息
                UserInfo userInfo = userInfoService.findById(item.getUserId());
                //创建满足返回值的vo类
                MovementVo movementVo = new MovementVo();
                //给vo类赋值
                movementVo.setUserInfo(userInfo);
                movementVo.setMovement(item);
                //判断如果redis里存入了已经“点赞”的标记，修改vo类中的点赞状态属性
                if (stringRedisTemplate.hasKey(StrUtil.format(ConstantUtil.MOVEMENT_LIKE, item.getId(), userId))) {
                    movementVo.setHasLiked(1);
                }
                //判断如果redis里存入了已经“喜欢”的标记，修改vo类中的喜欢状态属性
                if (stringRedisTemplate.hasKey(StrUtil.format(ConstantUtil.MOVEMENT_LOVE, item.getId(), userId))) {
                    movementVo.setHasLoved(1);
                }
                //存入vo类集合
                movementVos.add(movementVo);
            }
        }
        //把满足返回值的vo集合赋值给分页类
        pageBeanVo.setItems(movementVos);
        //返回页面
        return ResponseEntity.ok(pageBeanVo);
    }

    //动态点赞
    @LogWith(type = "0203")
    public ResponseEntity setMovementLike(String publishId) {
        //根据token获取userId
        Long userId = UserHolder.get().getId();
        //创建评论类
        Comment comment = new Comment();
        //给评论类赋值
        comment.setCreated(System.currentTimeMillis());
        comment.setPublishId(new ObjectId(publishId));
        comment.setCommentType(1);
        comment.setUserId(userId);
        //根据评论中的动态id获取动态详情
        Movement movement = movementService.findById(comment.getPublishId());
        comment.setPublishUserId(movement.getUserId());
        //调用业务层保存评论
        Integer likeCount = commentService.saveComment(comment);
        //调用redis存入一个已经“点赞”的标记
        stringRedisTemplate.opsForValue().set(StrUtil.format(ConstantUtil.MOVEMENT_LIKE, publishId, userId), "1");
        //点赞后 需要保存一条访客记录
        Visitor visitor = new Visitor();
        visitor.setDate(System.currentTimeMillis());
        visitor.setUserId(movement.getUserId());
        visitor.setVisitorUserId(userId);
        visitor.setScore(RandomUtil.randomDouble(60, 99));
        visitor.setFrom("圈子");
        visitorService.addVisitor(visitor);
        //记录MovementScore发布给MQ
        movementScoreMQSend.sendMovement(userId,movement.getId(),MovementScoreMQSend.MOVEMENT_LIKE);

        //返回页面点赞总数
        return ResponseEntity.ok(likeCount);
    }

    //动态取消点赞
    @LogWith(type = "0206")
    public ResponseEntity removeMovementLike(String publishId) {
        //根据token获取userId
        Long userId = UserHolder.get().getId();
        //根据动态id获取动态详情
        Movement movement = movementService.findById(new ObjectId(publishId));
        //调用业务层删除此条点赞记录 并返回删除后的点赞数
        Integer likeCount = commentService.removeComment(userId, 1, publishId);
        //删除redis中的点赞标记
        stringRedisTemplate.delete(StrUtil.format(ConstantUtil.MOVEMENT_LIKE, publishId, userId));
        //取消点赞后 需要保存一条访客记录
        Visitor visitor = new Visitor();
        visitor.setDate(System.currentTimeMillis());
        visitor.setUserId(movement.getUserId());
        visitor.setVisitorUserId(userId);
        visitor.setScore(RandomUtil.randomDouble(60, 99));
        visitor.setFrom("圈子");
        visitorService.addVisitor(visitor);
        //记录MovementScore发布给MQ
        movementScoreMQSend.sendMovement(userId,movement.getId(),MovementScoreMQSend.MOVEMENT_DISLIKE);
        //返回页面点赞数量
        return ResponseEntity.ok(likeCount);
    }

    //动态喜欢
    @LogWith(type = "0204")
    public ResponseEntity setMovementLove(String publishId) {
        //根据token获取userId
        Long userId = UserHolder.get().getId();
        //创建评论类
        Comment comment = new Comment();
        //给评论类赋值
        comment.setCreated(System.currentTimeMillis());
        comment.setPublishId(new ObjectId(publishId));
        comment.setCommentType(3);
        comment.setUserId(userId);
        //根据动态id获取动态详情
        Movement movement = movementService.findById(comment.getPublishId());
        comment.setPublishUserId(movement.getUserId());
        //调用业务层添加喜欢记录 并返回喜欢数量
        Integer loveCount = commentService.saveComment(comment);
        //调用redis存入一个已经“喜欢”的标记
        stringRedisTemplate.opsForValue().set(StrUtil.format(ConstantUtil.MOVEMENT_LOVE, publishId, userId), "1");
        //用户喜欢后 需要加入一条访客记录
        Visitor visitor = new Visitor();
        visitor.setDate(System.currentTimeMillis());
        visitor.setUserId(movement.getUserId());
        visitor.setVisitorUserId(userId);
        visitor.setScore(RandomUtil.randomDouble(60, 99));
        visitor.setFrom("圈子");
        visitorService.addVisitor(visitor);
        //记录MovementScore发布给MQ
        movementScoreMQSend.sendMovement(userId,movement.getId(),MovementScoreMQSend.MOVEMENT_LOVE);

        //返回喜欢数量
        return ResponseEntity.ok(loveCount);
    }

    //动态取消喜欢
    @LogWith(type = "0207")
    public ResponseEntity removeMovementLove(String publishId) {
        //根据token获取userId
        Long userId = UserHolder.get().getId();
        //根据动态id获取动态详情
        Movement movement = movementService.findById(new ObjectId(publishId));
        //调用业务层删除此条喜欢记录 并返回删除后的喜欢数
        Integer loveCount = commentService.removeComment(userId, 3, publishId);
        //删除redis中的喜欢标记
        stringRedisTemplate.delete(StrUtil.format(ConstantUtil.MOVEMENT_LOVE, publishId, userId));
        //取消喜欢后 需要保存一条访客记录
        Visitor visitor = new Visitor();
        visitor.setDate(System.currentTimeMillis());
        visitor.setUserId(movement.getUserId());
        visitor.setVisitorUserId(userId);
        visitor.setScore(RandomUtil.randomDouble(60, 99));
        visitor.setFrom("圈子");
        visitorService.addVisitor(visitor);
        //记录MovementScore发布给MQ
        movementScoreMQSend.sendMovement(userId,movement.getId(),MovementScoreMQSend.MOVEMENT_DISLOVE);

        //返回喜欢数量
        return ResponseEntity.ok(loveCount);
    }

    //查询动态详情页中的用户信息
    @LogWith(type = "0202")
    public ResponseEntity findOneMovement(String publishId) {
        Long userId = UserHolder.get().getId();
        //根据动态id查询动态详情
        Movement movement = movementService.findById(new ObjectId(publishId));
        //创建满足返回值的vo类 并赋值
        MovementVo movementVo = new MovementVo();
        UserInfo userInfo = userInfoService.findById(movement.getUserId());
        movementVo.setUserInfo(userInfo);
        movementVo.setMovement(movement);
        //查询动态详情页添加一条访客记录
        Visitor visitor = new Visitor();
        visitor.setDate(System.currentTimeMillis());
        visitor.setUserId(movement.getUserId());
        visitor.setVisitorUserId(userId);
        visitor.setScore(RandomUtil.randomDouble(60, 99));
        visitor.setFrom("圈子");
        visitorService.addVisitor(visitor);
        //记录MovementScore发布给MQ
        movementScoreMQSend.sendMovement(userId,movement.getId(),MovementScoreMQSend.MOVEMENT_BROWSE);

        //返回vo类
        return ResponseEntity.ok(movementVo);
    }

    //查询动态详情页中的所有评论
    public ResponseEntity findMovementCommentByPage(Integer pageNum, Integer pageSize, String publishId) {
        //调用业务层获取满足条件的评论分页类
        PageBeanVo pageBeanVo = commentService.findCommentByPage(publishId, pageNum, pageSize, 2);
        //创建满足返回值的vo类集合
        List<CommentVo> commentVos = new ArrayList<>();
        //获取分页类中的评论集合
        List<Comment> items = (List<Comment>) pageBeanVo.getItems();
        //判断非空 遍历
        if (CollectionUtil.isNotEmpty(items)) {
            for (Comment item : items) {
                //根据评论信息中的userId获取详细用户信息
                UserInfo userInfo = userInfoService.findById(item.getUserId());
                //创建vo类 并赋值
                CommentVo commentVo = new CommentVo();
                commentVo.setAvatar(userInfo.getAvatar());
                commentVo.setNickname(userInfo.getNickname());
                commentVo.setContent(item.getContent());
                commentVo.setId(item.getId().toHexString());
                commentVo.setCreateDate(DateUtil.formatDateTime(new Date(item.getCreated())));
                if (stringRedisTemplate.hasKey("content_like:"+item.getId()+"_"+item.getUserId())) {
                    commentVo.setHasLiked(1);
                }
                //添加到集合
                commentVos.add(commentVo);
            }
        }
        //把满足返回值的vo集合赋值给分页类
        pageBeanVo.setItems(commentVos);
        //返回分页类
        return ResponseEntity.ok(pageBeanVo);
    }

    //发布评论
    @LogWith(type = "0205")
    public void saveMovementComment(String publishId, String content) {

        Long userId = UserHolder.get().getId();
        //创建评论类 并赋值
        Comment comment = new Comment();
        comment.setCreated(System.currentTimeMillis());
        comment.setPublishId(new ObjectId(publishId));
        comment.setCommentType(2);
        comment.setUserId(userId);
        Movement movement = movementService.findById(new ObjectId(publishId));
        comment.setPublishUserId(movement.getUserId());
        comment.setContent(content);
        //给动态评论后 添加一条记录
        Visitor visitor = new Visitor();
        visitor.setDate(System.currentTimeMillis());
        visitor.setUserId(movement.getUserId());
        visitor.setVisitorUserId(userId);
        visitor.setScore(RandomUtil.randomDouble(60, 99));
        visitor.setFrom("圈子");
        visitorService.addVisitor(visitor);
        //记录MovementScore发布给MQ
        movementScoreMQSend.sendMovement(userId,movement.getId(),MovementScoreMQSend.MOVEMENT_COMMENT);
        //调用业务层保存
        commentService.saveComment(comment);
    }

    public ResponseEntity saveContentLike(ObjectId publishId) {
        Long userId = UserHolder.get().getId();
        Comment comment = new Comment();
        comment.setUserId(userId);
        comment.setCreated(System.currentTimeMillis());
        comment.setPublishId(publishId);
        comment.setCommentType(6);
        Comment commentById = commentService.findCommentById(publishId);
        comment.setPublishUserId(commentById.getUserId());
        Integer integer = commentService.addMovementCommentsLike(publishId,comment);
        stringRedisTemplate.opsForValue().set("content_like:"+publishId+"_"+userId,"1");
        return ResponseEntity.ok(integer);
    }

    public ResponseEntity delContentLike(ObjectId publishId) {
        Long userId = UserHolder.get().getId();
        Comment comment = commentService.findCommentById(publishId);
        Integer likeCount = commentService.delMovementCommentsLike(publishId, 6);
        stringRedisTemplate.delete("content_like:"+publishId+"_"+userId);
        return ResponseEntity.ok(likeCount);
    }
}
